home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume6 / newbatchb < prev    next >
Encoding:
Internet Message Format  |  1986-11-30  |  20.3 KB

  1. Subject: v06i053:  Usenet news batcher control program (newbatchB)
  2. Newsgroups: mod.sources
  3. Approved: rs@mirror.UUCP
  4.  
  5. Submitted by: Rich $alz for Chris Lewis
  6. Mod.sources: Volume 6, Issue 53
  7. Archive-name: newbatchB
  8.  
  9. [  This is the second of two batched news utility programs (BNUP, to use
  10.    an acronym).  It was written on a BSD4.3 machine, but it looks like
  11.    it would be fairly easy to convert to USG.  Chris Lewis had posted
  12.    this to the net shortly before he left it, and I cleaned up the
  13.    documentation and am publishing it here.  Both this program and
  14.    the previous one have some nice features; I look forward to the
  15.    next one that combines the best of both methods, portably.  --r$ ]
  16.  
  17. #!/bin/sh
  18. # This is a shell archive.  Remove anything before this line,
  19. # then unpack it by saving it in a file and typing "sh file".
  20. # Contents:  README batcher.1 batcher.ctrl batcher.c Makefile
  21.  
  22. echo x - README
  23. sed 's/^XX//' > "README" <<'@//E*O*F README//'
  24. XXThis program is a ``posthumous'' publication of softare Chris Lewis
  25. XXposted to the net.  I felt it was worthwhile, and decided to clean up
  26. XXthe documentation a bit and publish it in mod.sources.  This README,
  27. XXthe manpage, and the sample control file come from Chris's original
  28. XXposting, combined with additional information I gleaned from the source.
  29. XXRead carefully -- there might be errors in the documentation.
  30. XX        /Rich $alz,
  31. XX         Moderator of mod.sources
  32.  
  33.  
  34. XXNews admins!  Sick of having millions of cron entries, differing
  35. XX[cs7]sendbatch scripts, and blown out spool areas with your downstream
  36. XXfeeds?  Well, have I got something for you!
  37.  
  38. XXThe "batcher" program which works with 2.10.2 and 2.10.3 news, solves
  39. XXall of these problems (if your're lucky!).  You install it in
  40. XX/usr/lib/news along with a batch control file, "batcher.ctrl".  The
  41. XXcontrol file contains one line per down-stream site which describes how
  42. XXto send news to that site.
  43.  
  44. XXTo install, read these next few paragraphs and edit the source as
  45. XXappropriate.
  46. XX   +Batching instructions for all downstream sites is contained in one
  47. XX    file, instead of having to make customized *sendbatches (e.g.,
  48. XX    differing bits in compress, different grades, different batch
  49. XX    sizes).
  50.  
  51. XX   +You can speicfy the batch size for each site, tuning for various
  52. XX    link qualities.
  53.  
  54. XX   +If you have 4.3BSD UUCP, you can completely eliminate the chance
  55. XX    of filling up your spool area.  The control file lets you specify
  56. XX    the number of bytes allowable in the UUCP queue for each system;
  57. XX    the real batching is not invoked for a site until they make contact
  58. XX    and bring the queue size back down below the limit.
  59.  
  60. XX    This is done by 'popen("uuq -l -s<sitename>", "r")' to find out the
  61. XX    size of the queue for the site.  Non-4.3 sites can probably write
  62. XX    their own routine to scan UUCP "C." files to figure out how big the
  63. XX    queue is for a specific system.  If you don't have this uuq command,
  64. XX    #undef UUQ in the source.
  65.  
  66. XX   +If you are running on a 4.xBSD system, batcher will also not invoke
  67. XX    the real batching software if there is less than 5Mb free on the
  68. XX    UUCP spool file system.  This is done by doing "df /usr/spool/uucp"
  69. XX    which I believe works only on 4.[23]BSD systems.  If you can't do
  70. XX    this, #undef DFABLE in the source.  It should be fairly easy to
  71. XX    kludge something up for other sites, however.
  72.  
  73. XXNext, modify your news sys file so that each system you want to control
  74. XXthis way has batching turned on:
  75. XX    mnetor:....:F:/usr/spool/batch/mnetor
  76. XXAdd entries for those sites in /usr/lib/news/batcher.ctrl.  Information
  77. XXon the control file is given in the manpage, and in the sample file
  78. XXdistributed.
  79.  
  80. XXFinally, via cron, run batcher setuid news with either the name of a
  81. XXsite to feed, or a "class" (which'll run all sites with that class).
  82.  
  83. XXThis software has made an incredible difference on this site.  We give
  84. XXfull feeds to 7 sites, plus smaller ones to about another ten.  Until
  85. XXthis was installed, we had to disable batching to one site or another
  86. XXevery second day.  And we blew spool areas on weekends.  We haven't had
  87. XXto touch *anything* since this was installed.  Even when sites have
  88. XXbeen unreachable for weeks on end.
  89.  
  90. XXChris Lewis
  91. XX    formerly at mnetor!clewis,
  92. XX    might now be reachable at utzoo!spectrix!clewis
  93. @//E*O*F README//
  94. chmod u=rw,g=rw,o=rw README
  95.  
  96. echo x - batcher.1
  97. sed 's/^XX//' > "batcher.1" <<'@//E*O*F batcher.1//'
  98. XX.TH BATCHER 1 LOCAL
  99. XX.SH NAME
  100. XXbatcher \- a new batching system for news
  101. XX.SH SYNOPSIS
  102. XX.B batcher
  103. XX[
  104. XX.IB \-c X
  105. XX]
  106. XX.br
  107. XX.B batcher
  108. XX[
  109. XX.I site
  110. XX]
  111. XX.IR "(typically run out of " cron ".)"
  112. XX.SH DESCRIPTION
  113. XX.I Batcher
  114. XXis designed to feed batched USENET neighbors in a controlled, orderly fashion.
  115. XXIn particular, it is designed to replace multiple [cs7]sendbatch scripts,
  116. XXand put an upper limit on the amount of data that may be queued for a site.
  117. XXAt some sites, it is also possible to perform checks that will prevent
  118. XXoverflowing the filesystem that contains the UUCP spool directory.
  119. XX.PP
  120. XX.I Batcher
  121. XXreads the file
  122. XX.RI NEWSLIB/batch.ctrl
  123. XXto determine how to send data to each site.
  124. XXThis control file contains one line per down\-stream site that describes how
  125. XXto send news to that site.
  126. XX.I Batcher
  127. XXitself is run out of
  128. XX.I cron
  129. XXas necessary, setuid news.
  130. XXIt should be given a single argument, either the name of a site to batch the
  131. XXnews for, or a class
  132. XX.RI ( batcher
  133. XXwill then do work on all sites in that class).
  134. XX.PP
  135. XXIn the control file, lines beginning with a pound sign (``#'') are ignored.
  136. XXData lines, one per site being fed, are comprised of seven colon\-separated
  137. XXfields:
  138. XX.RS
  139. XXsite:class:compress:uux_flags:b_size:q_size:uux_command
  140. XX.RE
  141. XX.TP site
  142. XXThe name of the site being fed.  This is the same as the name in the news
  143. XX.I sys
  144. XXfile.
  145. XXBy using the ``F'' protocol in news, the file
  146. XX.IR /usr/spool/batch/ site
  147. XXshould contain the full\-pathname list of articles intended for that site.
  148. XX.TP class
  149. XXA single letter; the default is ``z.''  Executing ``batcher \-cX'' works on all
  150. XXsites in class ``X.''
  151. XX.TP compress
  152. XXThis is the command line to use to call
  153. XX.IR compress ;
  154. XXthe default is no compression.
  155. XXIf something is specified here, it is used as an intermediate pipe, and the
  156. XX``uux'' field defaults to ``uux\ ...\ !cunbatch.''
  157. XX.TP uux_flags
  158. XXThese are the flags to insert on the uux command line.  As distributed, he
  159. XXdefault is ``\-r\ \-z\ \gd'' (just queue work, only acknowledge failures,
  160. XXgrade d transmission).
  161. XX.TP b_size
  162. XXThe size of batches, default is 100K.
  163. XXThis is passed on to the standard
  164. XX.I batcher
  165. XXprogram.
  166. XX.TP q_size
  167. XXThe maximum UUCP queue size, default is 500K.  As distributed, the program
  168. XXparses the output of the 4.3BSD command ``uuq\ \-l\ \-sSITE.''
  169. XXIf the queue is currently greater than ``q_size,'' no work is done for
  170. XXthe site until it drops below that number.
  171. XX.TP uux_command
  172. XXThis can be a complete replacement for the uux command.  The default is
  173. XX``uux\ \-\ <uuxflags>\ site!<unbatch|cunbatch>.''
  174. XX.PP
  175. XXTo use
  176. XX.IR batcher ,
  177. XXmodify your news
  178. XX.I sys
  179. XXfile so that all (most?) (some??) sites use the batching protocol, e.g.:
  180. XX.RS
  181. XXmnetor:net.flame,net.rumor,net.bizarre:F:/usr/spool/batch/mnetor
  182. XX.RE
  183. XXNote that the batch filename must be the same name as the site being fed.
  184. XXNext edit the control file, placing sites in classes and with queue sizes
  185. XXthat seem appropriate.
  186. XXThen, edit
  187. XX.I /usr/lib/crontab
  188. XXto replace calls to the old batching programs with calls to
  189. XX.IR nbatcher .
  190. XX(It should be running setuid news.)
  191. XXYou will probably want to use both ``job class'' calls and explicitly\-named
  192. XXsites.
  193. XX.SH BUGS
  194. XXQueue and spool\-fillage checking is done via
  195. XX.I uuq
  196. XXand
  197. XX.IR df ,
  198. XXrespectively.  This is somewhat slow, but it is swamped by the execution
  199. XXof the batching itself.
  200. @//E*O*F batcher.1//
  201. chmod u=rw,g=rw,o=rw batcher.1
  202.  
  203. echo x - batcher.ctrl
  204. sed 's/^XX//' > "batcher.ctrl" <<'@//E*O*F batcher.ctrl//'
  205. XX#    SAMPLE BATCHER.CTRL FILE
  206. XX#
  207. XX#  Lines beginning with pound signs are ignored.  Data lines look like;
  208. XX#        site:class:compress:uux_flags:b_size:q_size:uux_command
  209. XX#  Where
  210. XX#    Site        = Name of downstream neighbor
  211. XX#    Class        = System class; "batcher -cX" does all sites in class X.
  212. XX#              Default class is z.
  213. XX#    Compress    = Anything here is intermediate pipe to the uux, also
  214. XX#              changes default uux_command (see below).
  215. XX#    Uux_flags    = Put in uux command if not given in field seven.
  216. XX#              Default is "-r -z -gd" (see below).
  217. XX#    B_size        = Size of batches; default is 100K.
  218. XX#    Q_size        = Size of UUCP queue; no work is done while # bytes
  219. XX#              in queue is greater than this.
  220. XX#    Uux_command    = Complete replacement for uux command.  Default is
  221. XX#              "uux - <uuxflags> site!<unbatch|cunbatch>" (see
  222. XX#              above).
  223. XX#  If a name does not exist, batcher won't send a batch.
  224. XX#
  225. XX#  SAMPLE ENTRIES
  226. XX#
  227. XX#    NORMAL NEWS FEEDS
  228. XXgenat::compress -C::::
  229. XXutcs::compress -C::::
  230. XXradha::compress::::
  231. XXtoram::compress:-n -r -gd:::
  232. XXyetti:z:compress -C::::
  233. XXlsuc::compress -C -b 13::::
  234. XXmicomvax::::::
  235. XX#
  236. XX#    NEW NEWS FEED COMING UP
  237. XXsyntron::compress -C::::
  238. XX#
  239. XX#    MOT NEWS FEEDS
  240. XXmotsj1:A::-n -r -gd:::
  241. XXmot:A::-n -r -gd:::
  242. XX#
  243. XX#    "-cX" NEWS FEEDS
  244. XXcxhq:A::-n -gB:::
  245. XXcxsea:A::-n -gB:::
  246. XXcxmso:A:compress -C:-n -gB:::
  247. XXcxsch:A:::20000::mail cxsch!ewa
  248. XXcxphx:A:::20000::mail cxphx!nms
  249. XXcxmd:A:::20000::mail cxmd!joe
  250. XXtest:A:::::mail clewis
  251. @//E*O*F batcher.ctrl//
  252. chmod u=rw,g=rw,o=rw batcher.ctrl
  253.  
  254. echo x - batcher.c
  255. sed 's/^XX//' > "batcher.c" <<'@//E*O*F batcher.c//'
  256. XX/*    Chris Lewis, June 1986    */
  257. XX#include <stdio.h>
  258. XX#if    defined(BSD4_2) || defined(BSD4_1C)
  259. XX#include <strings.h>
  260. XX#else
  261. XX#include <string.h>
  262. XX#endif
  263. XXextern char *malloc();
  264. XXextern void free();
  265.  
  266. XX#define    NUMFLDS    7
  267. XX#define    NAME    0
  268. XX#define    CLASS    1
  269. XX#define    COMPRESS 2
  270. XX#define    UUXFLAGS 3
  271. XX#define    SIZE    4
  272. XX#define    QSIZE    5
  273. XX#define    UUX    6
  274.  
  275. XX#define    UUQ    /* define this if you have BSD 4.3 uuq utility */
  276. XX#define    DFABLE    /* define this if "df /usr/spool/uucp" works on your system */
  277.  
  278. XX/* Take a look at these, too. */
  279. XX#ifdef    DEBUG
  280. XX#define    BATCHCTRL    "batcher.ctrl"
  281. XX#else
  282. XX#define    BATCHCTRL    "/usr/lib/news/batcher.ctrl"
  283. XX#endif
  284.  
  285. XX#define    BATCH    "/usr/spool/batch"
  286. XX#define    SBATCH    "/usr/lib/news/batch"
  287.  
  288.  
  289. XXint    fldlen[NUMFLDS] = {10, 2, 20, 10, 7, 10, 30};
  290.  
  291. XXstruct desc {
  292. XX    char         *flds[NUMFLDS];
  293. XX    struct desc    *next;
  294. XX} *head = (struct desc *) NULL, 
  295. XX  *dptr = (struct desc *) NULL;
  296.  
  297. XX#if    defined(BSD4_2) || defined(BSD4_1C)
  298. XX#define    strchr    index
  299. XX#endif
  300.  
  301. XXstruct desc *getflds();
  302.  
  303. XXint    verbose = 0;
  304. XXint    class;
  305. XXint    spoolok = 1;
  306.  
  307. XXlong    spoollim = 5000000;
  308.  
  309. XX/*
  310. XX *    main:
  311. XX *        - process arguments
  312. XX *        - read control file
  313. XX *        - for each system selected, see if there is any work,
  314. XX *            if so, go try to do it.
  315. XX */
  316.  
  317. XXmain(argc, argv)
  318. XXint    argc;
  319. XXchar    **argv; {
  320. XX    register char *p;
  321. XX    register struct desc *curptr;
  322. XX    argc--; argv++;
  323. XX    for (;argc > 0 && **argv == '-'; argv++) {
  324. XX        for (p = (*argv)+1; *p; p++)
  325. XX            switch(*p) {
  326. XX                case 'v':
  327. XX                    verbose = 1;
  328. XX                    break;
  329. XX                case 'c':
  330. XX                    class = *(p+1);
  331. XX                    if (class == 0)
  332. XX                        class = 'z';
  333. XX                    else
  334. XX                        p++;
  335. XX                    break;
  336. XX                default:
  337. XX                    fprintf(stderr, "batcher: Bad arg %s\n", *argv);
  338. XX                    exit(1);
  339. XX            }
  340. XX    }
  341. XX    readctrl();
  342. XX    if (!checkspool()) {
  343. XX        exit(0);
  344. XX    }
  345. XX    if (verbose)
  346. XX        dumpctrl();
  347. XX    if (class) {
  348. XX        for (curptr = head; curptr && spoolok; curptr = curptr->next) {
  349. XX            if (*(curptr->flds[CLASS]) == class &&
  350. XX                (chkbatch(curptr->flds[NAME], "") || 
  351. XX                chkbatch(curptr->flds[NAME], ".work")) &&
  352. XX                (spoolok = checkspool()))
  353. XX                doit(curptr->flds[NAME]);
  354. XX        }
  355. XX    }
  356. XX    while(*argv && spoolok) {
  357. XX        if (chkbatch(*argv, "") || chkbatch(*argv, ".work")) {
  358. XX            doit(*argv);
  359. XX        }
  360. XX        argv++;
  361. XX    }
  362. XX    exit(0);
  363.  
  364. XX}
  365.  
  366. XX/*
  367. XX *    readctrl:
  368. XX *
  369. XX *    Each line in the batch.ctrl file contains NUMFLDS colon-separated
  370. XX *    parameters.  This function reads each line, and calls getflds
  371. XX *    to separate out the parameters.  If getflds returns a system descriptor
  372. XX *    it is linked into the list of system descriptors.
  373. XX */
  374.  
  375. XXreadctrl() {
  376. XX    char    buf[BUFSIZ];
  377. XX    register char    *p;
  378. XX    register struct desc *ptr;
  379. XX    struct desc *getflds();
  380. XX    register FILE    *ctrl = fopen(BATCHCTRL, "r");
  381. XX    if (!ctrl) {
  382. XX        fprintf(stderr, "batcher: could not open %s file\n",
  383. XX            BATCHCTRL);
  384. XX        exit(1);
  385. XX    }
  386. XX    while (fgets(buf, sizeof(buf), ctrl)) {
  387. XX        if (buf[0] == '#')
  388. XX            continue;
  389. XX        p = buf + strlen(buf) - 1;
  390. XX        if (*p == '\n')
  391. XX            *p = '\0';
  392. XX        if ((ptr = getflds(buf)) && processctrl(ptr)) {
  393. XX            if (!head)
  394. XX                head = dptr = ptr;
  395. XX            else {
  396. XX                dptr->next = ptr;
  397. XX                dptr = ptr;
  398. XX            }
  399. XX            ptr->next = (struct desc *) NULL;
  400. XX        }
  401. XX    }
  402. XX    fclose(ctrl);
  403. XX}
  404.  
  405. XX/*
  406. XX *    dumpctrl:
  407. XX *
  408. XX *    If verbose is on, dump the tables
  409. XX */
  410.  
  411. XXdumpctrl() {
  412. XX    register struct desc *p;
  413. XX    register int i;
  414. XX    for (p = head; p; p = p->next) {
  415. XX        for (i = 0; i < NUMFLDS; i++)
  416. XX            printf("%-*s", fldlen[i], p->flds[i]);
  417. XX        printf("\n");
  418. XX    }
  419. XX}
  420.  
  421. XXchar *strsave();
  422.  
  423. XX/*
  424. XX *    getflds:
  425. XX *
  426. XX *    This routine parses a single line from the batch.ctrl file,
  427. XX *    and if successfully parsed and checked out, returns a system
  428. XX *    descriptor pointer
  429. XX */
  430.  
  431. XXstruct desc *
  432. XXgetflds(buf)
  433. XXchar    *buf; {
  434. XX    register int cnt;
  435. XX    char b2[100];
  436. XX    char *curp, *p;
  437. XX    int    len;
  438. XX    struct desc *dptr;
  439. XX    dptr = (struct desc *) malloc(sizeof (struct desc));
  440. XX    if (!dptr) {
  441. XX        fprintf(stderr, "batcher: Cannot malloc\n");
  442. XX        exit(1);
  443. XX    }
  444. XX    curp = buf;
  445. XX    for (cnt = 0; cnt < NUMFLDS; cnt++) {
  446. XX        if (cnt == (NUMFLDS - 1)) {
  447. XX            if (strchr(curp, ':')) {
  448. XX                fprintf(stderr, "batcher: too many colons: %s\n",
  449. XX                    buf);
  450. XX                free(dptr);
  451. XX                return(NULL);
  452. XX            }
  453. XX            p = curp + strlen(curp);
  454. XX        } else
  455. XX            p = strchr(curp, ':');
  456. XX        if (p == NULL) {
  457. XX            fprintf(stderr, "batcher: invalid format (%d): %s\n", 
  458. XX                cnt, buf);
  459. XX            free(dptr);
  460. XX            return(NULL);
  461. XX        }
  462. XX        len = p - curp;
  463. XX        if (len >= fldlen[cnt]) {
  464. XX            fprintf(stderr, "batcher: field %d too long: %s\n",
  465. XX                cnt+1, buf);
  466. XX            free(dptr);
  467. XX            return(NULL);
  468. XX        }
  469. XX        if (!(dptr->flds[cnt] = malloc(len + 1))) {
  470. XX            fprintf(stderr, "batcher: cannot malloc\n");
  471. XX            exit(1);
  472. XX        }
  473. XX        strncpy(dptr->flds[cnt], curp, len);
  474. XX        dptr->flds[cnt][len] = '\0';
  475. XX        curp = p + 1;
  476. XX    }
  477. XX    return(dptr);
  478. XX}
  479.  
  480. XX/*
  481. XX *    strsave:
  482. XX *    returns pointer to malloc'd copy of argument
  483. XX */
  484. XXchar *
  485. XXstrsave(s)
  486. XXchar    *s; {
  487. XX    register char *p = malloc(strlen(s) + 1);
  488. XX    if (!p) {
  489. XX        fprintf(stderr, "batcher: cannot malloc\n");
  490. XX        exit(1);
  491. XX    }
  492. XX    strcpy(p, s);
  493. XX    return(p);
  494. XX}
  495.  
  496. XX/*
  497. XX *    chkbatch:
  498. XX *
  499. XX *    return 1 if a batcher work file <batchdir>/<name><type> exists.
  500. XX */
  501.  
  502. XXchkbatch(name, type)
  503. XXchar    *name;
  504. XXchar    *type; {
  505. XX    char batch[BUFSIZ];
  506. XX    sprintf(batch, "%s/%s%s", BATCH, name, type);
  507. XX    if (access(batch, 04) == 0)
  508. XX        return(1);
  509. XX    else
  510. XX        return(0);
  511. XX}
  512.  
  513. XX/*
  514. XX *    doit:
  515. XX *
  516. XX *    This routine is called with the name of the system that has
  517. XX *    been determined to have work for it.  The system is searched
  518. XX *    for in the system descriptors.  If found, a "system" line
  519. XX *    is contructed from the tables, and executed if system has not
  520. XX *    exceeded it's UUCP queue limit.
  521. XX */
  522.  
  523. XXdoit(name)
  524. XXchar    *name; {
  525. XX    char    cmdbuf[BUFSIZ];
  526. XX    int    rc;
  527. XX    long    queuesize;
  528. XX    long    checkqueue(), checkspool();
  529. XX    long    queuemax;
  530. XX    register struct desc *ptr;
  531. XX    if (verbose)
  532. XX        printf("batcher: doing %s\n", name);
  533. XX    for (ptr = head; ptr; ptr = ptr->next)
  534. XX        if (!strcmp(ptr->flds[NAME], name)) {
  535. XX            /*    form the command line for batching    */
  536. XX            sprintf(cmdbuf, "%s %s/%s %s",
  537. XX                SBATCH, BATCH, name, ptr->flds[SIZE]);
  538. XX            if (*(ptr->flds[COMPRESS]))
  539. XX                sprintf(cmdbuf + strlen(cmdbuf), "|%s",
  540. XX                    ptr->flds[COMPRESS]);
  541. XX            /*    Find the queue limit    */
  542. XX            sprintf(cmdbuf + strlen(cmdbuf), "|%s", ptr->flds[UUX]);
  543. XX            if (1 != sscanf(ptr->flds[QSIZE], "%ld", &queuemax)) {
  544. XX                fprintf(stderr, "batcher: bad qmax field: %s\n",
  545. XX                    ptr->flds[QSIZE]);
  546. XX                return;
  547. XX            }
  548. XX            queuesize = checkqueue(ptr->flds[NAME]);
  549. XX            rc = 0;
  550. XX            /*    While we haven't exceeded the queue limit &
  551. XX                there's work to do, issue the command */
  552. XX            while (queuesize < queuemax && !rc && 
  553. XX                (chkbatch(ptr->flds[NAME], "") || 
  554. XX                   chkbatch(ptr->flds[NAME], ".work")) &&
  555. XX                   (spoolok = checkspool())) {
  556. XX#ifdef    DEBUG
  557. XX                printf("batcher: cmd: %s\n", cmdbuf);
  558. XX                rc = 1;
  559. XX#else
  560. XX                rc = system(cmdbuf);
  561. XX                queuesize = checkqueue(ptr->flds[NAME]);
  562. XX#endif
  563. XX            }
  564. XX            return;
  565. XX        }
  566. XX    fprintf(stderr, "batcher: no control line for %s\n", name);
  567. XX}
  568.  
  569. XX/*
  570. XX *    processctrl:
  571. XX *
  572. XX *    Check validity of batch.ctrl entries and supply defaults.
  573. XX */
  574. XXprocessctrl(ptr)
  575. XXstruct    desc *ptr; {
  576. XX    char    buf[100];
  577. XX    register char    *p, *uuxflags;
  578. XX    if (!ptr) return;
  579. XX    if (strlen(ptr->flds[NAME]) == 0) {
  580. XX        fprintf(stderr, "batcher: null system name\n");
  581. XX        free(ptr);
  582. XX        return(0);
  583. XX    }
  584.  
  585. XX    if (strlen(ptr->flds[QSIZE]) == 0) {
  586. XX        free(ptr->flds[QSIZE]);
  587. XX        ptr->flds[QSIZE] = strsave("500000");
  588. XX    }
  589.  
  590. XX    if (strlen(ptr->flds[CLASS]) == 0) {
  591. XX        free(ptr->flds[CLASS]);
  592. XX        ptr->flds[CLASS] = strsave("z");
  593. XX    }
  594.  
  595. XX    if (strlen(ptr->flds[SIZE]) == 0) {
  596. XX        free(ptr->flds[SIZE]);
  597. XX        ptr->flds[SIZE] = strsave("100000");
  598. XX    }
  599.  
  600. XX    if (strlen(ptr->flds[UUXFLAGS]) == 0) {
  601. XX        free(ptr->flds[UUXFLAGS]);
  602. XX        ptr->flds[UUXFLAGS] = strsave("-r -z -gd");
  603. XX    }
  604.  
  605. XX    if (strlen(ptr->flds[UUX]) == 0) {
  606. XX        sprintf(buf, "uux - %s %s!%s", ptr->flds[UUXFLAGS],
  607. XX            ptr->flds[NAME], 
  608. XX            *ptr->flds[COMPRESS] ? "cunbatch" : "rnews");
  609. XX        ptr->flds[UUX] = strsave(buf);
  610. XX    }
  611. XX    return(1);
  612. XX}
  613.  
  614. XX/*
  615. XX *    checkqueue:
  616. XX *
  617. XX *    Logically, all this code does is return the size of the UUCP queue
  618. XX *    for system "name".
  619. XX *    I've taken the easy way out and popen'd "uuq" (4.3 BSD UUCP utility)
  620. XX *    to parse the first line, which looks something like this:
  621. XX *
  622. XX *    <systemname>: <n> jobs, <nnnn> bytes, ....
  623. XX *
  624. XX *    I merely look for the first comma, and sscanf the number following.
  625. XX *    A proper solution would be to dive in and parse the UUCP queues
  626. XX *    themselves, but: it's moderately difficult, and it changes from 
  627. XX *    system to system.
  628. XX */
  629.  
  630. XXlong
  631. XXcheckqueue(name)
  632. XXchar    *name; {
  633. XX#ifdef    UUQ
  634. XX    char buf[BUFSIZ];
  635. XX    long retval;
  636. XX    register char *p2;
  637. XX    FILE *p, *popen();
  638. XX    /* Gross, but the easiest way */
  639. XX    sprintf(buf, "uuq -l -s%s", name);
  640. XX    p = popen(buf, "r");
  641. XX    if (!fgets(buf, sizeof(buf), p)) {
  642. XX        return(0);
  643. XX    }
  644. XX    pclose(p);
  645. XX    p2 = strchr(buf, ',');
  646. XX    if (p2 && 1 == sscanf(p2+1, "%ld", &retval)) {
  647. XX        return(retval);
  648. XX    }
  649. XX    fprintf(stderr, "batcher: could not interpret %s\n", buf);
  650. XX    return(10000000);
  651. XX#else
  652. XX    return(10000000);
  653. XX#endif
  654. XX}
  655.  
  656. XX/*    This function returns the amount of free space on the spool
  657. XX    device, this may not work on your system - it reads the
  658. XX    second line from a "df /usr/spool/uucp" */
  659. XX#define    SPOOL "/usr/spool/uucp"
  660.  
  661. XXcheckspool() {
  662. XX#ifdef    DFABLE
  663. XX    char buf[100];
  664. XX    FILE *p, *popen();
  665. XX    long val;
  666. XX    sprintf(buf, "df %s", SPOOL);
  667. XX    if (!(p = popen(buf, "r"))) {
  668. XX        fprintf(stderr, "batcher: couldn't popen %s\n", buf);
  669. XX        return(0);
  670. XX    }
  671. XX    if (!fgets(buf, sizeof(buf), p)) {
  672. XX        fprintf(stderr, "batcher: no first line in df\n");
  673. XX        return(0);
  674. XX    }
  675. XX    if (!fgets(buf, sizeof(buf), p)) {
  676. XX        fprintf(stderr, "batcher: no second line in df\n");
  677. XX        return(0);
  678. XX    }
  679. XX    if (1 != sscanf(buf, "%*s %*ld %*ld %ld", &val)) {
  680. XX        fprintf(stderr, "batcher: couldn't get size from %s\n", buf);
  681. XX        return(0);
  682. XX    }
  683. XX    if (pclose(p)) {
  684. XX        fprintf(stderr, "batcher: DF failed\n");
  685. XX        return(0);
  686. XX    }
  687. XX    val *= 1024;
  688. XX    if (val < spoollim) {
  689. XX        printf("batcher: spool limit exceeded, %ld bytes left\n", val);
  690. XX        return(0);
  691. XX    } else
  692. XX        return(1);
  693. XX#else
  694. XX    return(1);
  695. XX#endif
  696. XX}
  697. @//E*O*F batcher.c//
  698. chmod u=rw,g=rw,o=rw batcher.c
  699.  
  700. echo x - Makefile
  701. sed 's/^XX//' > "Makefile" <<'@//E*O*F Makefile//'
  702. XXDEFS=-DBSD4_2
  703. XXCFLAGS    = -O $(DEFS)
  704. XXbatcher:    batcher.c
  705. XX    cc -o batcher $(CFLAGS) batcher.c
  706. @//E*O*F Makefile//
  707. chmod u=rw,g=rw,o=rw Makefile
  708.  
  709. echo Inspecting for damage in transit...
  710. temp=/tmp/sharin$$; dtemp=/tmp/sharout$$
  711. trap "rm -f $temp $dtemp; exit" 0 1 2 3 15
  712. cat > $temp <<\!!!
  713.       69     533    3297 README
  714.      102     557    3260 batcher.1
  715.       46     209    1374 batcher.ctrl
  716.      441    1376    9503 batcher.c
  717.        4      12      88 Makefile
  718.      662    2687   17522 total
  719. !!!
  720. wc  README batcher.1 batcher.ctrl batcher.c Makefile | sed 's=[^ ]*/==' | diff -b $temp - >$dtemp
  721. if test -s $dtemp
  722. then echo "Ouch [diff of wc output]:" ; cat $dtemp
  723. else echo "No problems found."
  724. fi
  725. exit 0
  726.  
  727.